﻿// See https://aka.ms/new-console-template for more information
using Mbs.Utils.Sockets;


Start();


static void Start()
{
    object lo = new object();
    int x = 0;
    Console.WriteLine("Test TCP Server Starting!");
    List<ITcpConnection> connections = new List<ITcpConnection>();
    ITcpServer server = new TcpServer(6060)
    {
        OnConnected = async (c) =>
        {
            Console.WriteLine($"{c.RemoteEndPoint} connected.");
            //c.NetConnection.Send("Hello Welcome to my hourse\n你好，欢迎光临");
            lock (lo)
            {
                //    c.NetConnection.Id = Interlocked.Increment(ref x); 
                connections.Add(c.NetConnection);
            }

            //c.NetConnection.Tag = new AAA() { dt=DateTime.Now}; //c.NetConnection.Id;
            Console.WriteLine($"connected from {c.RemoteEndPoint}:" + c.NetConnection.Id + "," + c.NetConnection.Tag + "m" + c.NetConnection.Name);
            string s = "hello,client! your id is:" + c.NetConnection.Id + ",total :" + connections.Count;
            c.NetConnection.Send(s, System.Text.Encoding.UTF8);
            Console.WriteLine(s);

        },
        OnReceived = async (c) =>
        {
            //if (c.NetConnection.Tag == null)
            //{
            //    Console.WriteLine($"Received from {c.RemoteEndPoint}:" + c.NetConnection.Id + "没有初始化"); ;
            //    c.NetConnection.Tag = new AAA() { dt = DateTime.Now }; //c.NetConnection.Id;

            //}
            //else
            //{
            //    Console.WriteLine($"Received from {c.RemoteEndPoint}:" + c.NetConnection.Id + ",Tag--->" + ((AAA)c.NetConnection.Tag).dt.ToString() + "<----,m" + c.NetConnection.Name);
            //}
            Console.WriteLine($"Received from {c.RemoteEndPoint}:");
            //Console.WriteLine(string.Join(" ", c.Buffers.Select(x => x.ToString("X2")).ToArray()));
            Console.WriteLine(string.Join(" ", c.Buffers.Select(x => x.ToString("X2")).ToArray()) + "-->" + System.Text.Encoding.UTF8.GetString(c.Buffers));
            c.NetConnection.Send("reply:" + System.Text.Encoding.UTF8.GetString(c.Buffers));

        },
        OnDisconnected = (c) =>
        {
            Console.WriteLine($"{c.RemoteEndPoint} disconnected.");
            if (c.NetConnection != null)
            {
                if (connections.Contains(c.NetConnection))
                {
                    lock (connections)
                    {
                        connections.Remove(c.NetConnection);
                        Console.WriteLine($"Left {connections.Count} connections");
                    }
                }
            }
        },
        OnStarted = (c) =>
        {
            Console.WriteLine($"{c.LocalEndPoint} started.");
        },
        OnStopped = (c) =>
        {
            Console.WriteLine($"{c.LocalEndPoint} stopped.");
        },
        OnException = (c) =>
        {
            Console.WriteLine($"{c.RemoteEndPoint} exception:{c.Exception.StackTrace.ToString()}.");
        },
        OnServerException = (c) =>
        {
            Console.WriteLine($"{c.LocalEndPoint} exception:{c.Exception.StackTrace.ToString()}.");
        }
    };
    // set keep alive
    server.UseKeepAlive(true, 500, 500);

    server.Start();

    Console.WriteLine("TcpServer Started!");

    try
    {
        while (true)
        {
            string key = Console.ReadLine();
            if (key == "c")
            {
                connections.Clear();
                x = 0;
            }


            Check(server);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

    try
    {
        server.Stop();
        Console.WriteLine("Socket.TcpServer Stopped!");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

    Console.ReadLine();
}

static void Check(ITcpServer server)
{
    try
    {
        foreach (var item in server.Connections)
        {
            int ret = -1;
            try
            {
                ret = item.Value.Send(new byte[0]);
            }
            catch (Exception ex)
            {
                ret = -2;
                Console.WriteLine(ex.Message);
            }
            finally
            {
                Console.WriteLine($"{item.Key}:{ret}");
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}


class AAA
{
    public DateTime dt { get; set; }
}